/*
 * XmlDocument.cpp
 *
 *  Created on: 2015年6月11日
 *      Author: chuanjiang.zh@qq.com
 */

#include "XmlBuilder.h"


namespace xml
{


std::ostream& operator << (std::ostream& os, const Attributes& attr)
{
    StringMap::const_iterator it = attr.begin();
    for (; it != attr.end(); ++ it)
    {
        if (it != attr.begin())
        {
            os << " ";
        }

        os << it->first << "=" << "\"";
        os << it->second << "\"";
    }
    return os;
}



Document::Document(Document::Option opt):
    m_ostream()
{
    if (opt == VERSION)
    {
        m_ostream << "<?xml version=\"1.0\"?>\n";
    }
    else if (opt == DECLARATION)
    {
        m_ostream << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    }
}

Document::Document(const char* declaration):
    m_ostream()
{
    m_ostream << declaration;
}

Document::Document(const std::string& declaration):
    m_ostream()
{
    m_ostream << declaration;
}

Document::~Document()
{
}


std::string Document::str()
{
    return m_ostream.str();
}

std::ostream& Document::getStream()
{
    return m_ostream;
}




Node::Node(Document& doc, const std::string& tag):
        m_ostream(doc.getStream()),
        m_tag(tag),
        m_closed(false),
        m_isText(false)
{
    m_firstChild = true;
    m_ostream << "<" << tag << ">";
}

Node::Node(Document& doc, const std::string& tag, const Attributes& attr):
        m_ostream(doc.getStream()),
        m_tag(tag),
        m_closed(false),
        m_isText(false)
{
    m_firstChild = true;
    m_ostream << "<" << tag << " " << attr << ">";
}

Node::Node(Document& doc, const std::string& tag, const Attributes& attr, const std::string& txt):
        m_ostream(doc.getStream()),
        m_tag(tag),
        m_closed(false),
        m_isText(true)
{
    m_firstChild = true;

    m_ostream << "<" << tag << " " << attr << ">";
    text(txt);
}

Node::Node(Document& doc, const std::string& tag, const std::string& txt):
        m_ostream(doc.getStream()),
        m_tag(tag),
        m_closed(false),
        m_isText(true)
{
    m_firstChild = true;

    m_ostream << "<" << tag << ">";
    text(txt);
}

Node::~Node()
{
    close();
}

void Node::close()
{
    if (!m_closed)
    {
        m_ostream << "</" << m_tag << ">\n";
        m_closed = true;
    }
}

bool Node::isOpen() const
{
    return !m_closed;
}


}
